﻿using Microsoft.Extensions.Caching.Memory;
using OneCard.Face8280Module.Entities.DTO.Cache;

namespace OneCard.Face8280Module.Service
{
    public class CacheService
    {
        public const string CacheDoorsKey = "doors";
        public const string CachePersonnelKey = "PersonnelIDs";
        public const string CachePersonnelCodeKey = "PersonnelCodes";

        public IMemoryCache Cache { get; set; }
        private static object lockCache = new object();
        public CacheService(IMemoryCache cache)
        {
            Cache = cache;
        }

        #region 门信息缓存
        /// <summary>
        /// 获取缓存的设备信息
        /// </summary>
        /// <param name="SN"></param>
        /// <returns></returns>
        public DTOCacheDoor GetDoor(string SN)
        {
            Dictionary<string, DTOCacheDoor> doors = Cache.Get<Dictionary<string, DTOCacheDoor>>(CacheDoorsKey);
            if (doors.ContainsKey(SN))
            {
                return doors[SN];
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 保存的设备信息
        /// </summary>
        /// <param name="door"></param>
        /// <returns></returns>
        public void SetDoor(DTOCacheDoor door)
        {
            var SN = door.EquptSN;
            Dictionary<string, DTOCacheDoor> doors = Cache.Get<Dictionary<string, DTOCacheDoor>>(CacheDoorsKey);
            if (!doors.ContainsKey(SN))
            {
                lock (lockCache)
                {
                    if (!doors.ContainsKey(SN))
                        doors.Add(SN, door);
                }

            }
            doors[SN] = door;

        }

        /// <summary>
        /// 检查重放攻击
        /// </summary>
        /// <param name="recordMD5"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        internal bool CheckReplayAttack(string recordMD5)
        {
            if (recordMD5 == null) return true;
            string value = Cache.Get<string>(recordMD5);
            if (value != null) return true;
            lock (lockCache)
            {
                value = Cache.Get<string>(recordMD5);
                if (value != null) return true;
                Cache.Set(recordMD5, recordMD5, TimeSpan.FromSeconds(120));
            }

            return false;
        }


        /// <summary>
        /// 保存的设备信息列表
        /// </summary>
        /// <param name="door"></param>
        /// <returns></returns>
        public void SetDoors(List<DTOCacheDoor> doors)
        {
            Cache.Set(CacheDoorsKey, doors.ToDictionary(d => d.EquptSN));
        }

        /// <summary>
        /// 获取缓存的门信息列表
        /// </summary>
        /// <param name="doors"></param>
        /// <returns></returns>
        public Dictionary<string, DTOCacheDoor> GetDoors()
        {
            return Cache.Get<Dictionary<string, DTOCacheDoor>>(CacheDoorsKey);
        }

        /// <summary>
        /// 更新门缓存信息
        /// </summary>
        /// <param name="doors"></param>
        /// <exception cref="NotImplementedException"></exception>
        internal void UpdateDoors(List<DTOCacheDoor> doors)
        {
            lock (lockCache)
            {
                var CacheDoors = GetDoors();
                foreach (var door in doors)
                {
                    if (CacheDoors.ContainsKey(door.EquptSN))
                    {
                        var cacheDoor = CacheDoors[door.EquptSN];
                        cacheDoor.EquptName = door.EquptName;
                        cacheDoor.EquptAddr = door.EquptAddr;
                        cacheDoor.LctnID = door.LctnID;
                        cacheDoor.LctnName = door.LctnName;
                        cacheDoor.UploadStatus = 0;
                    }

                }
            }
        }
        /// <summary>
        /// 删除设备
        /// </summary>
        /// <param name="doors"></param>
        internal void DeleteDoorCacheByDoorIDs(IEnumerable<int> doors)
        {
            lock (lockCache)
            {
                var CacheDoors = GetDoors().ToDictionary(d => d.Value.EquptID, v => v.Value);
                foreach (var doorID in doors)
                {
                    if (CacheDoors.ContainsKey(doorID))
                    {
                        CacheDoors.Remove(doorID);
                    }

                }
                SetDoors(CacheDoors.Values.ToList());
            }
        }


        #endregion

        #region 人员缓存
        /// <summary>
        /// 保存人员缓存
        /// </summary>
        /// <param name="p"></param>
        public void SetPersonnels(List<DTOCachePersonnel> Personnels)
        {
            Cache.Set(CachePersonnelKey, Personnels.ToDictionary(p => p.PersonnelID));
            Cache.Set(CachePersonnelCodeKey, Personnels.ToDictionary(p => p.PCode));
        }

        public Dictionary<long, DTOCachePersonnel> GetPersonnelCodes()
        {
            return Cache.Get<Dictionary<long, DTOCachePersonnel>>(CachePersonnelCodeKey);
        }

        public Dictionary<int, DTOCachePersonnel> GetPersonnelIDs()
        {
            return Cache.Get<Dictionary<int, DTOCachePersonnel>>(CachePersonnelKey);
        }


        public void UpdatePersonnels(List<DTOCachePersonnel> Personnels)
        {
            lock (lockCache)
            {
                var cachePersonnels = GetPersonnelIDs();
                foreach (var dbPersonnel in Personnels)
                {
                    if (cachePersonnels.ContainsKey(dbPersonnel.PersonnelID))
                    {
                        cachePersonnels[dbPersonnel.PersonnelID] = dbPersonnel;
                    }
                    else
                    {
                        cachePersonnels.Add(dbPersonnel.PersonnelID, dbPersonnel);
                    }
                }

                //重新生成编号字典
                var codePersonnels = cachePersonnels.ToDictionary(k => k.Value.PCode, v => v.Value);
                Cache.Set(CachePersonnelCodeKey, codePersonnels);
            }
        }

        public void DeletePersonnels(IEnumerable<int> IDList)
        {
            lock (lockCache)
            {
                var cachePersonnels = GetPersonnelIDs();
                foreach (var deleteID in IDList)
                {
                    if (cachePersonnels.ContainsKey(deleteID))
                    {
                        cachePersonnels.Remove(deleteID);
                    }
                }

                //重新生成编号字典
                var codePersonnels = cachePersonnels.ToDictionary(k => k.Value.PCode, v => v.Value);
                Cache.Set(CachePersonnelCodeKey, codePersonnels);
            }
        }

        #endregion


    }
}
